home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-M68K / SERIAL.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  14KB  |  449 lines

  1. /*
  2.  * include/linux/serial.h
  3.  *
  4.  * Copyright (C) 1992 by Theodore Ts'o.
  5.  * 
  6.  * Redistribution of this file is permitted under the terms of the GNU 
  7.  * Public License (GPL)
  8.  */
  9.  
  10. #ifndef _M68K_SERIAL_H
  11. #define _M68K_SERIAL_H
  12.  
  13.  
  14. /* m68k serial port types are numbered from 100 to avoid interference
  15.  * with the PC types (1..4)
  16.  */
  17. #define PORT_UNKNOWN    0
  18. #define PORT_8250    1
  19. #define PORT_16450    2
  20. #define PORT_16550    3
  21. #define PORT_16550A    4
  22. #define PORT_CIRRUS     5
  23. #define PORT_16650V2    7
  24. #define PORT_16750    8
  25.  
  26. #define SER_SCC_NORM    100    /* standard SCC channel */
  27. #define    SER_SCC_DMA    101    /* SCC channel with DMA support */
  28. #define    SER_MFP_CTRL    102    /* standard MFP port with modem control signals */
  29. #define    SER_MFP_BARE    103    /* MFP port without modem controls */
  30. #define    SER_MIDI    104    /* Atari MIDI */
  31. #define    SER_AMIGA    105    /* Amiga built-in serial port */
  32. #define SER_IOEXT    106    /* Amiga GVP IO-Extender (16c552) */
  33. #define SER_MFC_III    107    /* Amiga BSC Multiface Card III (MC68681) */
  34. #define SER_WHIPPET    108    /* Amiga Hisoft Whippet PCMCIA (16c550B) */
  35. #define SER_SCC_MVME    109    /* MVME162/MVME172 ports */
  36. #define SER_SCC_MAC    110    /* Macintosh SCC channel */
  37. #define SER_HPDCA    111    /* HP DCA serial */
  38. #define SER_SCC_BVME    112    /* BVME6000 ports */
  39.  
  40. struct serial_struct {
  41.     int    type;
  42.     int    line;
  43.     int    port;
  44.     int    irq;
  45.     int    flags;
  46.     int    xmit_fifo_size;
  47.     int    custom_divisor;
  48.     int    baud_base;
  49.     unsigned short    close_delay;
  50.     char    reserved_char[2];
  51.     int    hub6;
  52.     unsigned short    closing_wait; /* time to wait before closing */
  53.     unsigned short    closing_wait2; /* no longer used... */
  54.     int    reserved[4];
  55. };
  56.  
  57. /*
  58.  * For the close wait times, 0 means wait forever for serial port to
  59.  * flush its output.  65535 means don't wait at all.
  60.  */
  61. #define ASYNC_CLOSING_WAIT_INF    0
  62. #define ASYNC_CLOSING_WAIT_NONE    65535
  63.  
  64. /* This function tables does the abstraction from the underlying
  65.  * hardware:
  66.  *
  67.  *   init(): Initialize the port as necessary, set RTS and DTR and
  68.  *      enable interrupts. It does not need to set the speed and other
  69.  *      parameters, because change_speed() is called, too.
  70.  *   deinit(): Stop and shutdown the port (e.g. disable interrupts, ...)
  71.  *   enab_tx_int(): Enable or disable the Tx Buffer Empty interrupt
  72.  *      independently from other interrupt sources. If the int is
  73.  *      enabled, the transmitter should also be restarted, i.e. if there
  74.  *      are any chars to be sent, they should be put into the Tx
  75.  *      register. The real en/disabling of the interrupt may be a no-op
  76.  *      if there is no way to do this or it is too complex. This Tx ints
  77.  *      are just disabled to save some interrupts if the transmitter is
  78.  *      stopped anyway. But the restarting must be implemented!
  79.  *   check_custom_divisor(): Check the given custom divisor for legality
  80.  *      and return 0 if OK, non-zero otherwise.
  81.  *   change_speed(): Set port speed, character size, number of stop
  82.  *      bits and parity from the termios structure. If the user wants
  83.  *      to set the speed with a custom divisor, he is required to
  84.  *      check the baud_base first!
  85.  *   throttle(): Set or clear the RTS line according to 'status'.
  86.  *   set_break(): Set or clear the 'Send a Break' flag.
  87.  *   get_serial_info(): Fill in the baud_base and custom_divisor
  88.  *      fields of a serial_struct. It may also modify other fields, if
  89.  *      needed.
  90.  *   get_modem_info(): Return the status of RTS, DTR, DCD, RI, DSR and CTS.
  91.  *   set_modem_info(): Set the status of RTS and DTR according to
  92.  *      'new_dtr' and 'new_rts', resp. 0 = clear, 1 = set, -1 = don't change
  93.  *   ioctl(): Process any port-specific ioctl's. This pointer may be
  94.  *      NULL, if the port has no own ioctl's.
  95.  *   stop_receive(): Turn off the Rx part of the port, so no more characters
  96.  *      will be received. This is called before shutting the port down.
  97.  *   trans_empty(): Return !=0 if there are no more characters still to be
  98.  *      sent out (Tx buffer register and FIFOs empty)
  99.  *   check_open(): Is called before the port is opened. The driver can check
  100.  *      if that's ok and return an error code, or keep track of the opening
  101.  *      even before init() is called. Use deinit() for matching closing of the
  102.  *      port.
  103.  *
  104.  */
  105.  
  106. struct m68k_async_struct;
  107.  
  108. typedef struct {
  109.     void (*init)( struct m68k_async_struct *info );
  110.     void (*deinit)( struct m68k_async_struct *info, int leave_dtr );
  111.     void (*enab_tx_int)( struct m68k_async_struct *info, int enab_flag );
  112.     int  (*check_custom_divisor)( struct m68k_async_struct *info, int baud_base,
  113.                      int divisor );
  114.     void (*change_speed)( struct m68k_async_struct *info );
  115.     void (*throttle)( struct m68k_async_struct *info, int status );
  116.     void (*set_break)( struct m68k_async_struct *info, int break_flag );
  117.     void (*get_serial_info)( struct m68k_async_struct *info,
  118.                 struct serial_struct *retinfo );
  119.     unsigned int (*get_modem_info)( struct m68k_async_struct *info );
  120.     int  (*set_modem_info)( struct m68k_async_struct *info, int new_dtr,
  121.                    int new_rts );
  122.     int  (*ioctl)( struct tty_struct *tty, struct file *file,
  123.               struct m68k_async_struct *info, unsigned int cmd,
  124.               unsigned long arg );
  125.     void (*stop_receive)( struct m68k_async_struct *info );
  126.     int  (*trans_empty)( struct m68k_async_struct *info );
  127.     int  (*check_open)( struct m68k_async_struct *info, struct tty_struct *tty,
  128.                struct file *file );
  129. } SERIALSWITCH;
  130.  
  131. /*
  132.  * Definitions for m68k_async_struct (and serial_struct) flags field
  133.  */
  134. #define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
  135.                    on the callout port */
  136. #define ASYNC_FOURPORT  0x0002    /* Set OU1, OUT2 per AST Fourport settings */
  137. #define ASYNC_SAK    0x0004    /* Secure Attention Key (Orange book) */
  138. #define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
  139.  
  140. #define ASYNC_SPD_MASK    0x1030
  141. #define ASYNC_SPD_HI    0x0010    /* Use 56000 instead of 38400 bps */
  142.  
  143. #define ASYNC_SPD_VHI    0x0020  /* Use 115200 instead of 38400 bps */
  144. #define ASYNC_SPD_CUST    0x0030  /* Use user-specified divisor */
  145.  
  146. #define ASYNC_SKIP_TEST    0x0040 /* Skip UART test during autoconfiguration */
  147. #define ASYNC_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
  148. #define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
  149. #define ASYNC_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
  150. #define ASYNC_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
  151.  
  152. #define ASYNC_HARDPPS_CD    0x0800    /* Call hardpps when CD goes high  */
  153.  
  154. #define ASYNC_SPD_SHI    0x1000    /* Use 230400 instead of 38400 bps */
  155. #define ASYNC_SPD_WARP    0x1010    /* Use 460800 instead of 38400 bps */
  156.  
  157. #define ASYNC_FLAGS    0x1FFF    /* Possible legal async flags */
  158. #define ASYNC_USR_MASK 0x1430    /* Legal flags that non-privileged
  159.                  * users can set or reset */
  160.  
  161. /* Internal flags used only by drivers/char/m68kserial.c */
  162. #define ASYNC_INITIALIZED    0x80000000 /* Serial port was initialized */
  163. #define ASYNC_CALLOUT_ACTIVE    0x40000000 /* Call out device is active */
  164. #define ASYNC_NORMAL_ACTIVE    0x20000000 /* Normal device is active */
  165. #define ASYNC_BOOT_AUTOCONF    0x10000000 /* Autoconfigure port on bootup */
  166. #define ASYNC_CLOSING        0x08000000 /* Serial port is closing */
  167. #define ASYNC_CTS_FLOW        0x04000000 /* Do CTS flow control */
  168. #define ASYNC_CHECK_CD        0x02000000 /* i.e., CLOCAL */
  169.  
  170. #define ASYNC_INTERNAL_FLAGS    0xFF000000 /* Internal flags */
  171.  
  172. /*
  173.  * Serial input interrupt line counters -- external structure
  174.  * Four lines can interrupt: CTS, DSR, RI, DCD
  175.  */
  176. struct serial_icounter_struct {
  177.     int cts, dsr, rng, dcd;
  178.     int rx, tx;
  179.     int frame, overrun, parity, brk;
  180.     int buf_overrun;
  181.     int reserved[9];
  182. };
  183.  
  184.  
  185. #ifdef __KERNEL__
  186. /*
  187.  * This is our internal structure for each serial port's state.
  188.  * 
  189.  * Many fields are paralleled by the structure used by the serial_struct
  190.  * structure.
  191.  *
  192.  * For definitions of the flags field, see tty.h
  193.  */
  194.  
  195. #include <linux/termios.h>
  196. #include <linux/tqueue.h>
  197.  
  198. #include <linux/config.h>    /* for Mac SCC extensions */
  199.  
  200. #ifdef CONFIG_MAC
  201. #define NUM_ZSREGS    16
  202. struct mac_zschannel {
  203.     volatile unsigned char *control;
  204.     volatile unsigned char *data;
  205. };
  206. struct m68k_async_private;
  207. #endif
  208.  
  209. struct m68k_async_struct {
  210.     int            magic;
  211.     int            baud_base;
  212.     int            port;
  213.     int            irq;
  214.     int            flags;         /* defined in tty.h */
  215.     int            hub6;        /* HUB6 plus one */
  216.     int            type;
  217.     struct tty_struct     *tty;
  218.     int            read_status_mask;
  219.     int            ignore_status_mask;
  220.     int            timeout;
  221.     int            xmit_fifo_size;
  222.     int            custom_divisor;
  223.     int            x_char;    /* xon/xoff character */
  224.     int            close_delay;
  225.     unsigned short        closing_wait;
  226.     unsigned short        closing_wait2;
  227.     int            IER;     /* Interrupt Enable Register */
  228.     int            MCR;     /* Modem control register */
  229.     int            MCR_noint; /* MCR with interrupts off */
  230.     unsigned long        event;
  231.     unsigned long        last_active;
  232.     int            line;
  233.     int            count;        /* # of fd on device */
  234.     int            blocked_open; /* # of blocked opens */
  235.     long            session; /* Session of opening process */
  236.     long            pgrp; /* pgrp of opening process */
  237.     unsigned char         *xmit_buf;
  238.     int            xmit_head;
  239.     int            xmit_tail;
  240.     int            xmit_cnt;
  241.     struct tq_struct    tqueue;
  242.     struct termios        normal_termios;
  243.     struct termios        callout_termios;
  244.     struct wait_queue    *open_wait;
  245.     struct wait_queue    *close_wait;
  246.     struct wait_queue    *delta_msr_wait;
  247.     struct async_icount    icount;    /* kernel counters for the 4 input interrupts */
  248.     struct m68k_async_struct    *next_port; /* For the linked list */
  249.     struct m68k_async_struct    *prev_port;
  250.     void            *board_base; /* board-base address for use with
  251.                         boards carrying several UART's,
  252.                         like some Amiga boards. */
  253.     unsigned short        nr_uarts;    /* UART-counter, that indicates
  254.                         how many UART's there are on
  255.                         the board.  If the board has a
  256.                         IRQ-register, this can be used
  257.                         to check if any of the uarts,
  258.                         on the board has requested an
  259.                         interrupt, instead of checking
  260.                         IRQ-registers on all UART's */
  261.     SERIALSWITCH        *sw;        /* functions to manage this port */
  262. #ifdef CONFIG_MAC
  263.     struct m68k_async_private    *private;
  264. #endif
  265. };
  266.  
  267. #ifdef CONFIG_MAC
  268. struct m68k_async_private {
  269.     struct m68k_async_info    *zs_next;    /* For IRQ servicing chain */
  270.     struct mac_zschannel    *zs_channel;    /* Channel registers */
  271.     struct mac_zschannel    *zs_chan_a;    /* A side registers */
  272.     unsigned char        read_reg_zero;
  273.  
  274.     char            soft_carrier;    /* Use soft carrier on this */
  275.     char            break_abort;    /* console, process brk/abrt */
  276.     char            kgdb_channel;    /* Kgdb running on this channel */
  277.     char            is_cons;    /* Is this our console. */
  278.     unsigned char        tx_active;    /* character being xmitted */
  279.     unsigned char        tx_stopped;    /* output is suspended */
  280.  
  281.     /* We need to know the current clock divisor
  282.      * to read the bps rate the chip has currently
  283.      * loaded.
  284.      */
  285.     unsigned char        clk_divisor;    /* May be 1, 16, 32, or 64 */
  286.     int            zs_baud;
  287.  
  288.     /* Current write register values */
  289.     unsigned char        curregs[NUM_ZSREGS];
  290.  
  291.     /* Values we need to set next opportunity */
  292.     unsigned char        pendregs[NUM_ZSREGS];
  293.  
  294.     char            change_needed;
  295. };
  296. #endif
  297. #define SERIAL_MAGIC 0x5301
  298.  
  299. /*
  300.  * The size of the serial xmit buffer is 1 page, or 4096 bytes
  301.  */
  302. #define SERIAL_XMIT_SIZE 4096
  303.  
  304. /*
  305.  * Events are used to schedule things to happen at timer-interrupt
  306.  * time, instead of at rs interrupt time.
  307.  */
  308. #define RS_EVENT_WRITE_WAKEUP    0
  309.  
  310. /* number of characters left in xmit buffer before we ask for more */
  311. #define WAKEUP_CHARS 256
  312.  
  313. /* Export to allow PCMCIA to use this - Dave Hinds */
  314. extern int register_serial(struct serial_struct *req);
  315. extern void unregister_serial(int line);
  316. extern struct m68k_async_struct rs_table[];
  317. extern task_queue tq_serial;
  318.  
  319.  
  320. /*
  321.  * This routine is used by the interrupt handler to schedule
  322.  * processing in the software interrupt portion of the driver.
  323.  */
  324. static __inline__ void rs_sched_event(struct m68k_async_struct *info, int event)
  325. {
  326.     info->event |= 1 << event;
  327.     queue_task(&info->tqueue, &tq_serial);
  328.     mark_bh(SERIAL_BH);
  329. }
  330.  
  331. static __inline__ void rs_receive_char( struct m68k_async_struct *info,
  332.                         int ch, int err )
  333. {
  334.     struct tty_struct *tty = info->tty;
  335.     
  336.     if (tty->flip.count >= TTY_FLIPBUF_SIZE)
  337.         return;
  338.     tty->flip.count++;
  339.     switch(err) {
  340.     case TTY_BREAK:
  341.         info->icount.brk++;
  342.         if (info->flags & ASYNC_SAK)
  343.             do_SAK(tty);
  344.         break;
  345.     case TTY_PARITY:
  346.         info->icount.parity++;
  347.         break;
  348.     case TTY_OVERRUN:
  349.         info->icount.overrun++;
  350.         break;
  351.     case TTY_FRAME:
  352.         info->icount.frame++;
  353.         break;
  354.     }
  355.     *tty->flip.flag_buf_ptr++ = err;
  356.     *tty->flip.char_buf_ptr++ = ch;
  357.     info->icount.rx++;
  358.     tty_flip_buffer_push(tty);
  359. }
  360.  
  361. static __inline__ int rs_get_tx_char( struct m68k_async_struct *info )
  362. {
  363.     unsigned char ch;
  364.     
  365.     if (info->x_char) {
  366.         ch = info->x_char;
  367.         info->icount.tx++;
  368.         info->x_char = 0;
  369.         return( ch );
  370.     }
  371.  
  372.     if (info->xmit_cnt <= 0 || info->tty->stopped || info->tty->hw_stopped)
  373.         return( -1 );
  374.  
  375.     ch = info->xmit_buf[info->xmit_tail++];
  376.     info->xmit_tail &= SERIAL_XMIT_SIZE - 1;
  377.     info->icount.tx++;
  378.     if (--info->xmit_cnt < WAKEUP_CHARS)
  379.         rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
  380.     return( ch );
  381. }
  382.  
  383. static __inline__ int rs_no_more_tx( struct m68k_async_struct *info )
  384. {
  385.     return( info->xmit_cnt <= 0 ||
  386.             info->tty->stopped ||
  387.             info->tty->hw_stopped );
  388. }
  389.  
  390. static __inline__ void rs_dcd_changed( struct m68k_async_struct *info, int dcd )
  391.  
  392. {
  393.     /* update input line counter */
  394.     info->icount.dcd++;
  395.     wake_up_interruptible(&info->delta_msr_wait);
  396.  
  397.     if (info->flags & ASYNC_CHECK_CD) {
  398. #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
  399.         printk("ttyS%d CD now %s...", info->line,
  400.                dcd ? "on" : "off");
  401. #endif        
  402.         if (dcd) {
  403.             wake_up_interruptible(&info->open_wait);
  404.         } else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
  405.                  (info->flags & ASYNC_CALLOUT_NOHUP))) {
  406. #ifdef SERIAL_DEBUG_OPEN
  407.             printk("scheduling hangup...");
  408. #endif
  409.             if (info->tty)
  410.                 tty_hangup(info->tty);
  411.         }
  412.     }
  413. }
  414.  
  415.  
  416. void rs_stop( struct tty_struct *tty );
  417. void rs_start( struct tty_struct *tty );
  418.  
  419. static __inline__ void rs_check_cts( struct m68k_async_struct *info, int cts )
  420. {
  421.     /* update input line counter */
  422.     info->icount.cts++;
  423.     wake_up_interruptible(&info->delta_msr_wait);
  424.     
  425.     if ((info->flags & ASYNC_CTS_FLOW) && info->tty) {
  426.         if (info->tty->hw_stopped) {
  427.             if (cts) {
  428. #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
  429.                 printk("CTS tx start...");
  430. #endif
  431.                 info->tty->hw_stopped = 0;
  432.                 rs_start( info->tty );
  433.                 rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
  434.                 return;
  435.             }
  436.         } else {
  437.             if (!cts) {
  438.                 info->tty->hw_stopped = 1;
  439.                 rs_stop( info->tty );
  440.             }
  441.         }
  442.     }
  443. }
  444.  
  445.  
  446. #endif /* __KERNEL__ */
  447.  
  448. #endif /* _M68K_SERIAL_H */
  449.